package org.geom.curve.helix;

import java.util.ArrayList;

import org.geom.Maths;
import org.geom.Point3D;
import org.geom.Vector3D;
import org.geom.curve.Curve;
import org.geom.curve.ICurve;

public class EnhancedElicoide extends Curve {

	public static String U = "u";
	
	//---------------------------------------------------------------------- class vars
	
	private ICurve trunk;
	private Elicoide helix;
	
	private float _u = 30f;
	
	//---------------------------------------------------------------------- contructors
	
	public EnhancedElicoide(ICurve curve, Elicoide elicoide) {
		this.setCurve(curve);
		this.setElicoide(elicoide);
	}

	//---------------------------------------------------------------------- overrides
	
	@Override
	public ArrayList<Point3D> getPoints() {
		// TODO Auto-generated method stub
		float t=0;
		ArrayList<Point3D> pts = new ArrayList<Point3D>();
		
		for(int i=0; i<Curve.length; i++) {
			t = Maths.mapProportion(i, 0, Curve.length, 0, 1);
			pts.add( sample(t));
		}
		//System.out.println("StrangeElicoide > sample > t:"+t);
		
		return pts;
	}

	//---------------------------------------------------------------------- abstract implementation

	@Override
	public Point3D sample(float u) {
		Vector3D 		
		n = trunk.normal(u),
		b = trunk.binormal(u), 
		t = trunk.tangent(u);

		Point3D 
		p = trunk.sample(u);
		
		float 
		r = helix.r,
		k = helix.k;
		

		//P(t) + rcos(t*l)N(t) + rsen(t*l)B(t) + kT(t)
		
		float l = Maths.PI*_u;
		
		return new Point3D(
				p.x + 
				r*Maths.cos(u*l)*n.x +
				r*Maths.sin(u*l)*b.x + 
				k*u*t.x
				,
				p.y + 
				r*Maths.cos(u*l)*n.y +
				r*Maths.sin(u*l)*b.y + 
				k*u*t.y
				,
				p.z + 
				r*Maths.cos(u*l)*n.z +
				r*Maths.sin(u*l)*b.z  +
				k*u*t.z
				);
	}
	

	@Override
	protected Vector3D derivateI(float t) {
		// TODO : foo
		return new Vector3D();
	}

	@Override
	protected Vector3D derivateII(float t) {
		// TODO : foo
		return new Vector3D();
	}
	

	public void setCurve(ICurve curve) {
		this.trunk = curve;
	}

	public ICurve getCurve() {
		return trunk;
	}

	public void setElicoide(Elicoide helix) {
		this.helix = helix;
	}

	public Elicoide getElicoide() {
		return helix;
	}

	@Override
	public float getArc() {
		return trunk.getArc();
	}

	
	public void setU(float t, boolean increment) {
		if(increment)_u += t;
		else _u=t;
	}
	public float getParameterU() {
		return _u;
	}

}
